//
//  NotificationCenter+Ex.swift
//  Pods
//
//  Created by 100Years on 2025/11/19.
//
import Foundation

public typealias NotificationClosure = (Notification) -> Void

private var notificationClosuresKey: Void?

extension NotificationCenter {
    
    public func addObserver(
        for observer: NSObject,
        name: NSNotification.Name,
        object: Any? = nil,
        using closure: @escaping NotificationClosure
    ) {
        let container = Self.getClosuresContainer(for: observer)
        let key = NotificationKey(name: name, object: object as AnyObject?)
        
        // ✅ 修复1：通过 .closures 访问字典
        container.closures[key] = closure
        
        if !container.didRegisterProxy {
            addObserver(observer, selector: #selector(NSObject.__notification_proxy_handler(_:)), name: nil, object: nil)
            container.didRegisterProxy = true
        }
    }
}

// ✅ 修复2：使用 ObjectIdentifier
private struct NotificationKey: Hashable {
    let name: NSNotification.Name
    let objectIdentifier: ObjectIdentifier?

    init(name: NSNotification.Name, object: AnyObject?) {
        self.name = name
        self.objectIdentifier = object.map { ObjectIdentifier($0) }
    }
}

private final class ClosuresContainer {
    var didRegisterProxy = false
    var closures: [NotificationKey: NotificationClosure] = [:] // 字典类型明确
}

private extension NotificationCenter {
    static func getClosuresContainer(for observer: NSObject) -> ClosuresContainer {
        if let existing = objc_getAssociatedObject(observer, &notificationClosuresKey) as? ClosuresContainer {
            return existing
        }
        let container = ClosuresContainer()
        objc_setAssociatedObject(observer, &notificationClosuresKey, container, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        return container
    }
}

private extension NSObject {
    @objc func __notification_proxy_handler(_ notification: Notification) {
        guard let container = objc_getAssociatedObject(self, &notificationClosuresKey) as? ClosuresContainer else {
            return
        }
        
        let key = NotificationKey(name: notification.name, object: notification.object as AnyObject?)
        if let closure = container.closures[key] {
            closure(notification)
            return
        }
        
        // 可选：如果 add 时 object=nil，也匹配所有 object
        let wildcardKey = NotificationKey(name: notification.name, object: nil)
        if let closure = container.closures[wildcardKey] {
            closure(notification)
        }
    }
}
